home *** CD-ROM | disk | FTP | other *** search
- /*
-
- NanoTech - a 3d game engine
- Copyright (C) 1996 Sean Lane Fuller
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Sean Lane Fuller
- 124 Autumn Lane
- Tullahoma, TN 37388
- 615-393-4550
- email: fuller@edge.net
-
- */
-
-
- #include <dos.h>
- #include <mem.h>
- #include <bios.h>
- #include <math.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <graph.h>
- #include "pix.h"
- #include "keyboard.h"
- #include "sbuffer.h"
-
- int background;
- unsigned int pix_tbl[MAXNUMYPIXELS];
-
- char *pix_mem;
- char *pix_buf;
- unsigned char *screen = (unsigned char *)0xa0000;
-
- void pix_lineclip( int x1, int y1, int x2, int y2, int color );
- #define PIX_MAXVERTS 10
-
- #define INPUT_STATUS_1 0x3da //Input Status 1 register
- #define BORDER_COLOR 0x7b
- #define BORDER_DELTA 3
-
- #define fixtoint(x) ((int)(x))
- #define fixtodbl(x) (x)
- #define inttofix(x) ((float)(x))
- #define dbltofix(x) (x)
-
- void refr(long *dest, long *source, int length);
- #pragma aux refr = " rep movsd " parm [EDI] [ESI] [ECX] modify [EDI ESI ECX];
-
- struct videoconfig vc;
-
- void pix_refresh() {
- int c;
- static int a=1, v=0;
- // wait for retrace
- // do {
- // c = inp(0x3da);
- // } while (!(c & 0x08) && !keys[ESC]);
-
- if (VIDMODE == _MRES256COLOR)
- refr(screen, pix_mem, 16000);
- else
- _putimage(0, 0, pix_buf, _GPSET);
- }
-
- /******************************************************************************
- * set palette registers
- *****************************************************************************/
- void pix_setup_palette(float f)
- {
- static char first = 1;
- char ch;
- float cd[16][3] = { { 64, 0, 0 }, {0, 64, 0}, {0, 0, 64},
- {64, 64, 0}, {64, 0, 64}, {0, 64, 64}, {64, 64, 64}, {64, 32, 16},
- { 64, 32, 0 }, {32, 64, 0}, {0, 32, 64},
- {64, 64, 32}, {64, 32, 64}, {32, 64, 64}, {64, 32, 64}, {32, 32, 16}};
- int c, i, dx = 0x3c8, bx = 0, cx;
- FILE *fp;
-
- /*
- asm mov dx,INPUT_STATUS_1
- WaitDE:
- asm in al,dx
- asm test al,08h
- asm jz WaitDE
- */
-
- for (cx=0; cx<256; cx++)
- {
- c = cx/16;
- i = cx%16;
- outp(dx, bx);
- dx++;
- outp(dx, (int)((cd[c][0]/16.0*f)*i));
- outp(dx, (int)((cd[c][1]/16.0*f)*i));
- outp(dx, (int)((cd[c][2]/16.0*f)*i));
- dx--;
- bx++;
- }
- if (first)
- {
- fp = fopen("palette.pal", "wb");
- for (cx = 0; cx < 256; cx++)
- {
- c = cx / 16;
- i = cx % 16;
- ch = cd[c][0] * i;
- fwrite(&ch, 1, 1, fp);
- ch = cd[c][0] * i;
- fwrite(&ch, 1, 1, fp);
- ch = cd[c][0] * i;
- fwrite(&ch, 1, 1, fp);
- }
- fclose(fp);
- first = 0;
- }
- }
-
- void pix_init()
- {
- union REGS r;
- unsigned int i;
- _setvideomode(VIDMODE);
- _setfillmask(_GPSET);
- _setplotaction(_GPSET);
- _getvideoconfig(&vc);
- pix_buf = malloc(_imagesize(0, 0, MAXX, MAXY));
- pix_mem = &pix_buf[_imagesize(0, 0, MAXX, MAXY) - NUMXPIXELS*NUMYPIXELS];
- _getimage(0, 0, MAXX, MAXY, pix_buf);
- for (i=0; i<=MAXY; i++) pix_tbl[i] = i * (MAXX+1);
- pix_setup_palette(1.0);
- pix_cls(0);
- }
-
- #define pix_addr(x, y) (pix_tbl[y] + x)
-
- void pix_term()
- {
- // union REGS r;
- // r.h.ah = 0x00;
- // r.h.al = 3;
- // int386(0x10, &r, &r);
- _setvideomode(_TEXTC80);
- }
-
- #define pix_set(x,y,color) pix_mem[pix_addr((x),(y))] = color
-
- void pix_pset(int x, int y, int color)
- {
- pix_set(x, y, color);
- }
-
- void pix_cls(int background)
- {
- memset(pix_mem, background, (unsigned int)(MAXX+1)*(unsigned int)(MAXY+1));
- }
-
- void pix_line(int xa, int ya, int xb, int yb, short color)
- {
- int dx, dy, absdx, absdy, i, pa;
- short pos;
- int g, r, c, inc1, inc2, f, offs;
- dy = yb - ya;
- if ( dy == 0 )
- {
- /* Horizontal lines */
- if (xb < xa)
- {
- for(; xb <= xa; xb++ )
- {
- pix_set(xb, ya, color);
- }
- }
- else
- {
- for(; xa <= xb; xa++ )
- {
- pix_set(xa, ya, color);
- }
- }
- return;
- }
- dx = xb - xa;
- if ( dx == 0 )
- {
- /* Vertical Lines */
- if (yb < ya)
- {
- for(; yb <= ya; yb++, pa+=80 )
- {
- pix_set(xa, yb, color);
- }
- }
- else
- {
- for(; ya <= yb; ya++, pa += 80 )
- {
- pix_set(xa, ya, color);
- }
- }
- return;
- }
- if ( dx > 0 )
- {
- if ( dy < 0 ) pos = 0;
- else pos = 1;
- }
- else
- {
- if ( dy < 0 ) pos = 1;
- else pos = 0;
- }
- if ( abs( dx ) > abs( dy ) )
- {
- if ( dx > 0 ) { c = xa; r = ya; f = xb; }
- else { c = xb; r = yb; f = xa; }
- inc1 = abs( dy + dy );
- g = abs( dy ) * 2 - abs( dx );
- inc2 = ( abs( dy ) - abs( dx ) ) * 2;
- if ( pos )
- {
- while ( c <= f )
- {
- pix_set(c, r, color);
- c++;
- if ( g >= 0 ) { r++; g += inc2; }
- else g += inc1;
- }
- return;
- }
- else
- {
- while ( c <= f )
- {
- pix_set(c, r, color);
- c++;
- if ( g > 0 ) { r--; g += inc2; }
- else g+=inc1;
- }
- return;
- }
- }
- else
- {
- if ( dy > 0 ) { c=ya; r=xa; f=yb; }
- else { c=yb; r=xb; f=ya; }
- inc1 = abs( dx + dx );
- g = abs( dx ) * 2 - abs( dy );
- inc2 = ( abs( dx ) - abs( dy )) * 2;
- if ( pos )
- {
- if (c <= f)
- {
- pix_set(r, c, color);
- LOOP3:
- c++;
- if ( g >= 0 ) {
- r++; g+=inc2;
- if (c > f) goto EXIT_LOOP3;
- pix_set(r, c, color);
- }
- else
- {
- g+=inc1;
- if (c > f) goto EXIT_LOOP3;
- pix_set(r, c, color);
- }
- goto LOOP3;
- EXIT_LOOP3:
- ;
- }
- return;
- }
- else
- {
- if (c <= f)
- {
- pix_set(r, c, color);
- LOOP4:
- c++;
- if ( g >= 0 ) {
- r--; g+=inc2;
- if (c > f) goto EXIT_LOOP4;
- pix_set(r, c, color);
- }
- else
- {
- g+=inc1;
- if (c > f) goto EXIT_LOOP4;
- pix_set(r, c, color);
- }
- goto LOOP4;
- EXIT_LOOP4:
- ;
- }
- }
- }
- }
-
- void pix_disp_char(int c, unsigned int x, unsigned int y, int fgd, int bkgd)
- {
- unsigned char *ctbl = (unsigned char *)0xffa6e;
- int ctbli = c << 3;
- unsigned int scri = pix_addr(x, y);
- unsigned int i, j, b;
- for (i=0; i<8; i++)
- {
- b = ctbl[ctbli];
- for (j=0; j<4; j++)
- {
- if (b & 0x080) pix_mem[scri] = fgd /* - j */;
- else if (bkgd != 0) pix_mem[scri] = bkgd;
- scri++;
- b <<= 2;
- }
- if (bkgd != 0) pix_mem[scri] = bkgd;
- ctbli++;
- scri += (MAXX + 1) - 4;
- }
- }
-
- void pix_disp_str(char *s, int x, int y, int fgd, int bkgd)
- {
- int ox = x;
- while (*s)
- {
- if (*s == '\n')
- {
- x = ox;
- y += 8;
- }
- else
- {
- pix_disp_char(*s, x, y, fgd, bkgd);
- x += 5;
- }
- s++;
- }
- }
-
-
- void pix_pop_msg(char *format, int fgd, int bkgd)
- {
- int i, j, height=1, width=0, x, y;
- char msg[4096];
- char *s;
- va_list argptr;
- // va_start(argptr, bkgd);
- // vsprintf(msg, format, argptr);
- strcpy(msg, format);
- i = 0;
- s = msg;
- j = 0;
- // compute dimensions
- while (*s)
- {
- if (*s == '\n')
- {
- if (j > width) width = j;
- j = 0;
- height++;
- }
- else j++;
- s++;
- i++;
- }
- if (j > width) width = j;
- width *= 5;
- height <<= 3;
- y = NUMYPIXELS/2 - height/2;
- x = NUMXPIXELS/2 - width/2;
- pix_disp_str(msg, x + 1, y + 1, 1, bkgd);
- pix_disp_str(msg, x, y, fgd, 0);
- pix_line(x, y, x + width, y, fgd);
- pix_line(x + width, y, x + width, y + height, fgd);
- pix_line(x + width, y + height, x, y + height, fgd);
- pix_line(x, y + height, x, y, fgd);
- }
-
- void pix_wire( int vert_x[], int vert_y[], int no_verts, int color)
- {
- int i, j;
- i = no_verts - 1;
- pix_line(vert_x[i], vert_y[i], vert_x[0], vert_y[0], color);
- i = 0; j = 1;
- while (j < no_verts)
- {
- pix_line(vert_x[i], vert_y[i],
- vert_x[j], vert_y[j], color);
- j++; i++;
- }
- }
-
- int pix_pop_yn(char *msg, int fgd, int bkgd)
- {
- pix_pop_msg(msg, fgd, bkgd);
- pix_refresh();
- }
-
-
- struct PCXHEADER{
- unsigned char manu, hard, encod, bitpx;
- unsigned int x1, y1, x2, y2;
- unsigned int hres, vres;
- unsigned char palette[48];
- unsigned char vmode, nplanes;
- unsigned int bytesPerLine;
- char unused[128-68];
- } ;
-
-
- int getbyte(int *c, int *count, FILE *in)
- {
- if (feof(in)) return EOF;
- *c = getc(in) & 0xFF;
- if ((*c & 0xC0) == 0xC0) {
- *count = *c & 0x3F;
- if (feof(in)) return EOF;
- *c = getc(in) & 0xFF;
- }
- else *count = 1;
- return NULL;
- }
-
- void pix_loadpcx(char *buffer, char *filename, int setup_palette)
- {
- int c, count, bx, dx, cx;
- unsigned int i;
- char *scr = buffer;
- FILE *in;
- in = fopen(filename, "rb");
- if (in == NULL) return;
-
- /* setup the palette */
- dx = 0x3c8; bx = 0;
- fseek(in, -768, SEEK_END);
- for (cx=0; cx<256; cx++)
- {
- unsigned char red, green, blue;
- red = getc(in);
- green = getc(in);
- blue = getc(in);
- if (setup_palette)
- {
- outp(dx, bx);
- }
- dx++;
- if (setup_palette)
- {
- outp(dx, red >> 2);
- outp(dx, green >> 2);
- outp(dx, blue >> 2);
- }
- dx--;
- bx++;
- }
-
-
- i = 0;
- rewind(in);
- fseek(in, 128L, SEEK_SET);
- while (getbyte(&c, &count, in) != EOF)
- {
- while (count--) {
- scr[i] = c;
- i++;
- if (i >= (MAXX + 1) * (MAXY + 1)) goto quit;
- }
- }
- quit:
- fclose(in);
- }
-
- void box(int x1, int y1, int x2, int y2, int c)
- {
- // extern char *pix_mem;
- int w, h, i, j, a1, a2;
- if (x2 < 0) return;
- if (y2 < 0) return;
- if (x1 > MAXX) return;
- if (y1 > MAXY) return;
- if (x1 < 0) x1 = 0;
- if (y1 < 0) { j = -y1; y1 = 0; } else j = 0;
- if (x2 > MAXX) x2 = 319;
- if (y2 > MAXY) y2 = MAXY;
- w = x2 - x1 + 1;
- h = y2 - y1 + 1;
- a1 = pix_tbl[y1] + x1;
- a2 = pix_tbl[y2] + x2;
- while (a1 <= a2)
- {
- for (i=0; i<w; i++)
- {
- pix_mem[a1++] = c;
- }
- a1 += NUMXPIXELS - w;
- j++;
- }
- }
-
- union outcode
- {
- struct
- {
- unsigned code0: 1; /* x < 0 */
- unsigned code1: 1; /* y < 0 */
- unsigned code2: 1; /* x > MAXX */
- unsigned code3: 1; /* y > MAXY */
- } ocs;
- short outcodes;
- };
-
- void pix_lineclip( int x1, int y1, int x2, int y2, short color )
- {
- register union outcode oc1;
- register union outcode oc2;
- short inside;
- short outside;
- int temp;
-
- oc1.outcodes = 0; oc2.outcodes = 0;
- oc1.ocs.code0 = ( x1 < 0 );
- oc1.ocs.code1 = ( y1 < 0 );
- oc1.ocs.code2 = ( x1 > MAXX );
- oc1.ocs.code3 = ( y1 > MAXY );
-
- oc2.ocs.code0 = ( x2 < 0 );
- oc2.ocs.code1 = ( y2 < 0 );
- oc2.ocs.code2 = ( x2 > MAXX );
- oc2.ocs.code3 = ( y2 > MAXY );
-
- inside = ((oc1.outcodes | oc2.outcodes) == 0);
- outside = ((oc1.outcodes & oc2.outcodes) != 0);
-
- while( !outside && !inside )
- { if ( oc1.outcodes == 0 )
- { temp = x1; x1 = x2; x2 = temp;
- temp = y1; y1 = y2; y2 = temp;
- temp = oc1.outcodes;
- oc1.outcodes = oc2.outcodes;
- oc2.outcodes = temp;
- }
-
- if ( oc1.ocs.code0 ) /*==== left ====*/
- {
- y1 += (long)(y2-y1) * (-x1) / (x2 - x1);
- x1 = 0;
- }
- else if ( oc1.ocs.code1 ) /*==== right =====*/
- {
- x1 += (long)(x2-x1) * (-y1) / (y2 - y1);
- /* x1 += (x2-x1) * ((-y1) / (y2 - y1)); */
- y1 = 0;
- }
- else if ( oc1.ocs.code2 ) /*===== above ======*/
- {
- y1 += (long)(y2-y1) * (MAXX - x1) / (x2 - x1);
- /* y1 += (y2-y1) * ((MAXY - x1) / (x2 - x1)); */
- x1 = MAXX;
- }
- else if ( oc1.ocs.code3 ) /*====== below =====*/
- {
- x1 += (long)(x2 - x1) * (MAXY - y1) / (y2 - y1);
- /* x1 += (x2 - x1) * ((MAXY - y1) / (y2 - y1)); */
- y1 = MAXY;
- }
- oc1.outcodes = 0;
- oc1.ocs.code0 = ( x1 < 0 );
- oc1.ocs.code1 = ( y1 < 0 );
- oc1.ocs.code2 = ( x1 > MAXX );
- oc1.ocs.code3 = ( y1 > MAXY );
- inside = ((oc1.outcodes | oc2.outcodes) == 0);
- outside = ((oc1.outcodes & oc2.outcodes) != 0);
- }
- if ( inside )
- {
- pix_line( x1, y1, x2, y2, color );
- }
- }
-